/*
 * Copyright 2007-2008 by Matthias Buch-Kromann <mbk.isv@cbs.dk>.
 * 
 * This file is part of the Open-source Dependency Toolkit (OSDT),
 * see http://code.google.com/p/open-source-dependency-toolkit. 
 * 
 * The OSDT is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * The OSDT is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with the OSDT in the file COPYING and COPYING.LESSER. If not, see
 * http://www.gnu.org/licenses.
 */

package org.osdtsystem.graphs;

import org.osdtsystem.values.NodeID;
import org.osdtsystem.values.Location;
import org.osdtsystem.values.Layer;
import org.osdtsystem.values.Feature;
import org.osdtsystem.values.EdgeID;
import java.util.List;
import org.osdtsystem.graphs.views.View;
import org.osdtsystem.graphs.views.ViewID;

/**
 * Interface for querying a graph about the nodes, edges, node and edge
 * features, and named layers in the graph.
 * @author Matthias Buch-Kromann <mbk.isv@cbs.dk>
 */
public interface GraphQueryInterface {
    // Layers
    /**
     * Returns the node layer name corresponding to a given node layer ID.
     * @param layer the node layer ID
     * @return the corresponding node layer name
     */
    public String layerName(Layer layer);

    /**
     * Returns the set of all node layers in the graph.
     * @return the set of all node layers in the graph.
     */
    public List<Layer> layers();
    
    /**
     * Returns the node layer ID corresponding to a given node layer name.
     * @param name the node layer name
     * @return the corresponding node layer ID
     */
    public Layer lookupLayer(String name);
   
    /**
     * Determines whether the graph contains a given layer. 
     * @param layer the given layer
     * @return <code>true</code> if the graph contains the layer, <code>false</code> otherwise
     */
    public boolean containsLayer(Layer layer);
        
    // Nodes
    /**
     * Returns the layer associated with the given node.
     * @param node the given node
     * @return the node layer associated with the node
     */
    public Layer nodeLayer(NodeID node);
    
    /**
     * Returns the set of all in-coming getEdges at a given node.
     * @param node the ending node of the in-coming getEdges
     * @return the list of edges that end at the given node
     */
    public List<EdgeID> inEdges(NodeID node);
    
    /**
     * Returns the set of all in-coming edges at a given node within a given
     * edge layer.
     * @param node the ending node of the in-coming edges
     * @param layer the edge layer containing the getEdges
     * @return the set of edges that end at the given node in the given layer
     */
    public List<EdgeID> inEdges(NodeID node, Layer layer);
    
    /**
     * Returns the set of all out-going getEdges at a given node.
     * @param node the starting node of the out-going getEdges
     * @return the set of getEdges that start at the given node
     */
    public List<EdgeID> outEdges(NodeID node);
    
    /**
     * Returns the set of all out-going getEdges at a given node within a
     * given edge layer.
     * @param node the starting node of the out-going getEdges
     * @param layer the edge layer containing the nodes
     * @return the set of getEdges that start at the given node in the given layer
     */
    public List<EdgeID> outEdges(NodeID node, Layer layer);
    
    /**
     * Returns the set of all in-coming and out-going getEdges at a given node.
     * @param node the node where the edge must either start or end
     * @return the set of getEdges connected to the given node
     */
    public List<EdgeID> edges(NodeID node);

    /**
     * Returns the set of all in-coming and out-going getEdges at a given node
     * within a given edge layer.
     * @param node the node where the edge must either start or end
     * @param layer the edge layer containing the getEdges
     * @return the set of getEdges connected to the given node within the given edge layer
     */
    public List<EdgeID> edges(NodeID node, Layer layer);
    
    /**
     * Returns the set of all nodes in the graph.
     * @return the set of all nodes
     */
    public List<NodeID> nodes();

    /**
     * Returns the set of all nodes in the graph in the given layer.
     * @param layer the given node layer
     * @return the set of all nodes
     */
    public List<NodeID> nodes(Layer layer);
    
    /**
     * Determines whether the graph contains a given node.
     * @param node the node
     * @return <code>true</code> if the graph contains the node, <code>false</code>
     * otherwise
     */
    public boolean containsNode(NodeID node);
    
    /**
     * Returns the node associated with a given name. 
     * @param name the name
     * @return the node associated with the name; returns <code>null</code> if 
     * there is no node with that name.
     */
    public NodeID lookupNamedNode(String name);
    
    // Edges
    /**
     * Returns the edge layer associated with the given edge.
     * @param edge the edge
     * @return the edge layer associated with the edge
     */
    public Layer edgeLayer(EdgeID edge);

    /**
     * Return the in-node associated with a given edge. Return <code>null</code>
     * if the edge is invalid. 
     * @param edge the edge
     * @return the associated in-node
     */
    public NodeID inNode(EdgeID edge);
    
    /**
     * Return the out-node associated with a given edge. Return <code>null</code>
     * if the edge is invalid. 
     * @param edge the edge
     * @return the associated out-node
     */
    public NodeID outNode(EdgeID edge);

    /**
     * Returns the set of all edges in the graph within the given edge layer. 
     * @param layer the layer
     * @return the set of all getEdges
     */
    public List<EdgeID> edges(Layer layer);
    
    /**
     * Returns the set of all getEdges in the graph. 
     * @return the set of all getEdges
     */
    public List<EdgeID> edges();
   
    /**
     * Determines whether the graph contains a given edge.
     * @param edge the edge
     * @return <code>true</code> if the graph contains the edge, <code>false</code>
     * otherwise
     */
    public boolean containsEdge(EdgeID edge);
    
    // Features at nodes and edges
    /**
     * Returns the set of feature IDs for all features that have been defined
     * for the given layer. 
     * @param layer the given layer
     * @return the set of defined features in the given layer
     */
    public List<Feature> features(Layer layer);

     /**
     * Return list of features for a layer possibly including internal features.
     * @param layer the layer
     * @param includeInternalFeatures <code>true</code> if internal features
     *     should be included in the list, <code>false</code> otherwise
     * @return the list of features for the given layer
     */
    public List<Feature> features(Layer layer, boolean includeInternalFeatures);
    
    /**
     * The layer containing the location.
     * @param loc the location
     * @return the layer containing the location
     */
    public Layer layer(Location loc);
    
    /**
     * Returns the value ID for a given local feature.
     * @param loc the location
     * @param feat the feature
     * @return the value for the given feature
     */
    public Object featureValue(Location loc, Feature feat);
    
    /**
     * Returns the decoded feature associated with a given feature or feature pointer.
     * @param f the feature or feature pointer
     * @return the associated feature
     */
    public Feature decodeFeature(Feature f);
    
    /**
     * Returns the decoded value associated with a given value or value pointer.
     * @param v the value or value pointer
     * @return the associated value
     */
    public Object decodeValue(Object v);
    
    /**
     * Returns the set of features that are allowed at the given location.
     * @param location the location
     * @return the list of allowed features
     */
    public List<Feature> features(Location location);
    
    /**
     * Returns the set of features that are allowed at the given location.
     * @param location the location
     * @param includeInternalFeatures include internal features in the list
     * @return the list of allowed features
     */
    public List<Feature> features(Location location, boolean includeInternalFeatures);
    
    /**
     * Determines whether the given location permits the given feature. 
     * @param location layer the layer
     * @param feature the feature
     * @return <code>true</code> if the location permits the feature, <code>false</code> otherwise
     */
    public boolean permitsFeature(Location location, Feature feature);
    
    // Other
    
    /**
     * Return the first unused node id in the graph.
     * @return the first unused node id
     */
    public int nextNodeID();
    
    /**
     * Return the first unused edge id in the graph.
     * @return the first unused edge id
     */
    public int nextEdgeID();
    
    public int nextLayerID();
    
    /**
     * 
     * @param location
     * @return
     */
    public boolean containsLocation(Location location);
    
        
    /**
     * 
     * @param id
     * @return
     */
    public View view(ViewID id);
    
    public View view(String uniqueName);

    public ViewID viewID(String uniqueName);
    
    public ViewID viewID(View view);
    
    public String viewName(ViewID id);
    
    public String viewName(View view);
    
    /**
     * The views associated with the graph.
     * @return the list of views
     */
    public List<ViewID> views();

}
